package com.qdaily.supportlibrary.pulltorefresh.header;

import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;

import com.qdaily.supportlibrary.util.LocalDisplay;
import com.qdailylibrary.R;

public class RentalsSunDrawable extends Drawable implements Animatable {
    private static final int ANIMATION_DURATION = 1000;

    private final static float TOWN_RATIO = 0.22f;
    private static final float TOWN_INITIAL_SCALE = 1.0f;
    private static final float TOWN_FINAL_SCALE = 1.30f;

    private static final float SUN_FINAL_SCALE = 0.75f;
    private static final float SUN_INITIAL_ROTATE_GROWTH = 1.2f;
    private static final float SUN_FINAL_ROTATE_GROWTH = 1.5f;

    private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();

    private View mParent;
    private Matrix mMatrix;
    private Animation mAnimation;

    private int mTop;
    private int mScreenWidth;

    private int mTownHeight;

    private int mSunSize;
    private float mSunLeftOffset;
    private float mSunMinTopOffset;

    private float mPercent = 0.0f;
    private float mRotate = 0.0f;

    private Bitmap mSun;
    private Bitmap mTown;

    private boolean isRefreshing = false;

    private Context mContext;
    private int mTotalDragDistance;

    public RentalsSunDrawable(Context context, View parent) {
        mContext = context;
        mParent = parent;

        mMatrix = new Matrix();

        initiateDimens();
        createBitmaps();
        setupAnimations();
    }

    private Context getContext() {
        return mContext;
    }


    private void initiateDimens() {
        LocalDisplay.init(mContext);
        mTotalDragDistance = LocalDisplay.dp2px(240);

        mScreenWidth = getContext().getResources().getDisplayMetrics().widthPixels;

        mTownHeight = (int) (TOWN_RATIO * mScreenWidth);

        mSunLeftOffset = 0.3f * (float) mScreenWidth;
        mSunMinTopOffset = LocalDisplay.designedDP2px(90);
        mSunSize = LocalDisplay.designedDP2px(25);

        mTop = 0;
    }

    private void createBitmaps() {
        mTown = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.header_fg);
        mTown = Bitmap.createScaledBitmap(mTown, mScreenWidth, (int) (mScreenWidth * TOWN_RATIO), true);
        mSun = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.sun);
        mSun = Bitmap.createScaledBitmap(mSun, mSunSize, mSunSize, true);
    }

    public void offsetTopAndBottom(int offset) {
        mTop = offset;
        invalidateSelf();
    }

    @Override
    public void draw(Canvas canvas) {
        final int saveCount = canvas.save();
        canvas.translate(0, mTotalDragDistance - mTop);

        drawSun(canvas);
        drawTown(canvas);

        canvas.restoreToCount(saveCount);
    }

    private void drawTown(Canvas canvas)
    {
        Matrix matrix = mMatrix;
        matrix.reset();
        float offsetY = mTop - mTownHeight + LocalDisplay.designedDP2px(80);
        matrix.postScale(TOWN_INITIAL_SCALE, TOWN_INITIAL_SCALE);
        matrix.postTranslate(0, offsetY);
        canvas.drawBitmap(mTown, matrix, null);
    }

    private void drawSun(Canvas canvas) {
        Matrix matrix = mMatrix;
        matrix.reset();

        float dragPercent = mPercent;
        if (dragPercent > 1.0f) { // Slow down if pulling over set height
            dragPercent = (dragPercent + 9.0f) / 10;
        }

        float sunRadius = (float) mSunSize / 2.0f;
        float sunRotateGrowth = SUN_INITIAL_ROTATE_GROWTH;

        float offsetX = mSunLeftOffset;
        float offsetY = (mTotalDragDistance / 2) * (1.0f - dragPercent); // Move the sun up

        if (offsetY < mSunMinTopOffset) {
            offsetY = mSunMinTopOffset;
        }
        matrix.postTranslate(offsetX, offsetY);

        offsetX += sunRadius;
        offsetY += sunRadius;


        float r = (isRefreshing ? -360 : 360) * mRotate * (isRefreshing ? 1 : sunRotateGrowth);
        matrix.postRotate(r, offsetX, offsetY);

        canvas.drawBitmap(mSun, matrix, null);
    }

    public void setPercent(float percent) {
        mPercent = percent;
        setRotate(percent);
    }

    public void setRotate(float rotate) {
        mRotate = rotate;
        mParent.invalidate();
        invalidateSelf();
    }

    public void resetOriginals() {
        setPercent(0);
        setRotate(0);
    }

    @Override
    public void setAlpha(int alpha) {

    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {

    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public boolean isRunning() {
        return false;
    }

    @Override
    public void start() {
        mAnimation.reset();
        isRefreshing = true;
        mParent.startAnimation(mAnimation);
    }

    @Override
    public void stop() {
        mParent.clearAnimation();
        isRefreshing = false;
        resetOriginals();
    }

    private void setupAnimations() {
        mAnimation = new Animation() {
            @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                setRotate(interpolatedTime);
            }
        };
        mAnimation.setRepeatCount(Animation.INFINITE);
        mAnimation.setRepeatMode(Animation.RESTART);
        mAnimation.setInterpolator(LINEAR_INTERPOLATOR);
        mAnimation.setDuration(ANIMATION_DURATION);
    }

    public int getTotalDragDistance() {
        return mTotalDragDistance;
    }
}
